﻿using MahApps.Metro.Controls;
using Newtonsoft.Json;
using Prism.Commands;
using Prism.Events;
using Prism.Ioc;
using Prism.Mvvm;
using Prism.Regions;
using Prism.Services.Dialogs;
using SIMS.Common.Events;
using SIMS.Common.Models;
using SIMS.Common.RestClient;
using SIMS.Shared.DTO;
using SIMS.Shared.Models;
using SIMS.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;

namespace SIMS.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private readonly IEventAggregator _eventAggregator;
        private readonly IContainerExtension _container;
        private readonly IRegionManager _regionManager;
        private readonly IDialogService _dialogService;
        private readonly HttpRestClient _httpClient;

        public MainWindowViewModel(IContainerExtension container,
            IRegionManager regionManager,
            IEventAggregator eventAggregator,
            IDialogService dialogService,
            HttpRestClient httpClient)
        {
            _container = container;
            _regionManager = regionManager;
            _eventAggregator = eventAggregator;
            _dialogService = dialogService;
            _httpClient = httpClient;

            //登录窗口
            _dialogService.ShowDialog("Login", null, LoginCallback, "MetroDialogWindow");

             
            _eventAggregator.GetEvent<LoginEvent>().Subscribe(OnLogout);
            _eventAggregator.GetEvent<LoadingEvent>().Subscribe(OnShowLoading);
        }

        public IRegionManager RegionManager
        {
            get { return _regionManager; }
        }

        private async void LoginCallback(IDialogResult dialogResult)
        {
            if (dialogResult.Result != ButtonResult.OK)
            {
                Application.Current.Shutdown();
            }
            else
            {
                await CreateMenuItems();
            }
        }

        private DelegateCommand loadedCommand;

        public DelegateCommand LoadedCommand
        {
            get
            {
                if (loadedCommand == null)
                {
                    loadedCommand = new DelegateCommand(Loaded);
                }
                return loadedCommand;
            }
        }

        private void Loaded()
        {
            InitInfo();
        }

        private void InitInfo()
        {
            var header = _container.Resolve<Header>();
            IRegion headerRegion = _regionManager.Regions["HeaderRegion"];
            headerRegion.Add(header);

            var footer = _container.Resolve<Footer>();
            IRegion footerRegion = _regionManager.Regions["FooterRegion"];
            footerRegion.Add(footer);

            var welcome = _container.Resolve<Welcome>();
            IRegion welcomeRegion = _regionManager.Regions["ContentRegion"];
            welcomeRegion.Add(welcome);
        }

        private void Navigation(string source)
        {
            _regionManager.RequestNavigate("ContentRegion", source);
        }

        private void OnLogout()
        {
            Application.Current.MainWindow.Hide();
            this._dialogService.ShowDialog("Login", null, (result) =>
            {
                if (result.Result != ButtonResult.OK)
                {
                    Application.Current.Shutdown();
                }
                else
                {
                    Application.Current.MainWindow.Show();
                }
            }, "MetroDialogWindow");
        }

        private void OnShowLoading(bool isLoading)
        {
            this.IsLoading = isLoading;
        }

        private bool isLoading;

        public bool IsLoading
        {
            get { return isLoading; }
            set { SetProperty(ref isLoading, value); }
        }

        private List<HamburgerMenuItemBase> _navItems;

        public List<HamburgerMenuItemBase> NavItems
        {
            get
            {
                return _navItems;
            }
            set
            {
                SetProperty(ref _navItems, value);
            }
        }

        private async Task CreateMenuItems()
        {
            var navItems = new List<HamburgerMenuItemBase>();
            var userRights = await GetUserRights();
            if (userRights != null)
            {
                var parents = userRights.Where(x => x.ParentId == null).OrderBy(r => r.SortId);
                foreach (var parent in parents)
                {
                    navItems.Add(new HamburgerMenuHeaderItem() { Label = parent.MenuName });
                    var subItems = userRights.Where(r => r.ParentId == parent.Id).OrderBy(r => r.SortId);
                    foreach (var subItem in subItems)
                    {
                        navItems.Add(new HamburgerMenuGlyphItem() { Label = subItem.MenuName, Tag = subItem.Url, Glyph = subItem.Icon });
                    }
                }
                UserInfo.Instance.Roles = String.Join(',', userRights.Select(r => r.RoleName).Distinct().ToList());
            }
            NavItems = navItems;
        }

        private async Task<List<UserRightDTO>?> GetUserRights()
        {
            Dictionary<string, object> parameters = new Dictionary<string, object>();
            parameters["userId"] = UserInfo.Instance.Id;

            ApiRequest request = new ApiRequest();
            request.Method = RestSharp.Method.Get;
            request.Parameters = parameters;
            request.Route = Api.ROLE_GETUSERRIGHTS;
            ResponseResultModel response = await _httpClient.Execute(request);
            if (response.code == 1)
            {
                var rights = JsonConvert.DeserializeObject<List<UserRightDTO>>(JsonConvert.SerializeObject(response.data));
                return rights;
            }
            return null;
        }

        private DelegateCommand<object> navCommand;

        public DelegateCommand<object> NavCommand
        {
            get
            {
                if (navCommand == null)
                {
                    navCommand = new DelegateCommand<object>(Navigation);
                }
                return navCommand;
            }
        }

        private void Navigation(object obj)
        {
            var menuItem = (HamburgerMenuItem)obj;
            if (menuItem != null)
            {
                var tag = menuItem.Tag;
                if (tag != null)
                {
                    _regionManager.RequestNavigate("ContentRegion", tag.ToString());
                }
            }
        }
    }
}
